import './style.css'

/**
 * API 方法类型定义
 */
type HttpMethod = 'GET' | 'POST' | 'DELETE';

/**
 * API 配置类型定义
 */
interface ApiConfig {
    name: string;
    url: string;
    methods: HttpMethod[];  // 支持的请求方法
    defaultMethod: HttpMethod;  // 默认请求方法
    description: string;
    example: any;
}

/**
 * API 接口配置
 */
const API_CONFIG: ApiConfig[] = [
    {
        name: "生成 /api/generate",
        url: "http://localhost:11434/api/generate",
        methods: ['POST'],
        defaultMethod: 'POST',
        description: "文本生成接口",
        example: {
            model: "qwen2.5:0.5b",
            prompt: "为什么天空是蓝色的？",
            stream: false
        }
    },
    {
        name: "对话 /api/chat",
        url: "http://localhost:11434/api/chat",
        methods: ['POST'],
        defaultMethod: 'POST',
        description: "聊天对话接口",
        example: {
            model: "qwen2.5:0.5b",
            messages: [
                { role: "user", content: "你好" }
            ],
            stream: false
        }
    },
    {
        name: "向量 /api/embeddings",
        url: "http://localhost:11434/api/embeddings",
        methods: ['POST'],
        defaultMethod: 'POST',
        description: "文本向量化接口",
        example: {
            model: "qwen2.5:0.5b",
            prompt: "Hello world"
        }
    },
    {
        name: "拉取 /api/pull",
        url: "http://localhost:11434/api/pull",
        methods: ['POST'],
        defaultMethod: 'POST',
        description: "拉取模型接口",
        example: {
            name: "qwen2.5:0.5b"
        }
    },
    {
        name: "模型列表 /api/tags",
        url: "http://localhost:11434/api/tags",
        methods: ['GET'],
        defaultMethod: 'GET',
        description: "获取模型列表",
        example: {}
    },
    {
        name: "模型信息 /api/show",
        url: "http://localhost:11434/api/show",
        methods: ['POST'],
        defaultMethod: 'POST',
        description: "获取模型详细信息",
        example: {
            name: "qwen2.5:0.5b"
        }
    },
    {
        name: "复制模型 /api/copy",
        url: "http://localhost:11434/api/copy",
        methods: ['POST'],
        defaultMethod: 'POST',
        description: "复制现有模型",
        example: {
            source: "qwen2.5:0.5b",
            destination: "qwen2.5:0.5b-copy"
        }
    },
    {
        name: "删除模型 /api/delete",
        url: "http://localhost:11434/api/delete",
        methods: ['DELETE'],
        defaultMethod: 'DELETE',
        description: "删除指定模型",
        example: {
            name: "qwen2.5:0.5b"
        }
    }
];

document.addEventListener('DOMContentLoaded', () => {
    let pendingDeleteTimestamp: number | null = null;

    // 获取页面元素引用
    const elements = {
        themeToggle: document.getElementById('themeToggle'),
        copyButton: document.getElementById('copyResponse'),
        responseOutput: document.getElementById('responseOutput')!,
        urlSelect: document.getElementById('urlSelect') as HTMLSelectElement,
        urlInput: document.getElementById('url') as HTMLInputElement,
        paramsTextarea: document.getElementById('params') as HTMLTextAreaElement,
        methodSelect: document.getElementById('method') as HTMLSelectElement,
        statusCode: document.getElementById('statusCode'),
        loading: document.getElementById('loading'),
        historyList: document.getElementById('historyList'),
        clearHistory: document.getElementById('clearHistory'),
        formatButton: document.getElementById('formatParams') as HTMLButtonElement,
        templateSelect: document.getElementById('templateSelect') as HTMLSelectElement,
        timeoutInput: document.getElementById('timeout') as HTMLInputElement,
        confirmDialog: document.getElementById('confirmDialog'),
        confirmClear: document.getElementById('confirmClear'),
        cancelClear: document.getElementById('cancelClear'),
        undoHistory: document.getElementById('undoHistory'),
        deleteDialog: document.getElementById('deleteDialog'),
        confirmDelete: document.getElementById('confirmDelete'),
        cancelDelete: document.getElementById('cancelDelete'),
        responseContainer: document.querySelector('.response-container'),
        responseHeader: document.querySelector('.response-header'),
        paramsContainer: document.querySelector('.params-container'),
        paramsHeader: document.querySelector('.params-header'),
        exportHistory: document.getElementById('exportHistory'),
        historyPanel: document.querySelector('.history-panel'),
        historyHeader: document.querySelector('.history-header'),
    };

    /**
     * 本地存储键名
     */
    const STORAGE_KEYS = {
        THEME: 'ollama-api-tester-theme',
        LAST_API: 'ollama-api-tester-last-api',
        HISTORY: 'ollama-api-tester-history'
    };

    /**
     * 历史记录类型定义
     */
    interface HistoryItem {
        timestamp: number;
        url: string;
        method: string;
        params: string;
        success: boolean;
        response?: string;  // 添加响应结果字段
        statusCode?: string;  // 添加状态码字段
    }

    // 在顶部添加撤销历史栈
    interface UndoHistoryItem {
        type: 'delete' | 'clear';
        items: HistoryItem[];
    }

    let undoStack: UndoHistoryItem[] = [];

    /**
     * 格式化时间
     */
    function formatTime(timestamp: number): string {
        const date = new Date(timestamp);
        return date.toLocaleString('zh-CN', {
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit'
        });
    }

    /**
     * 更新历史记录显示
     */
    function updateHistoryList() {
        if (!elements.historyList) return;

        try {
            const history = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY) || '[]') as HistoryItem[];
            elements.historyList.innerHTML = history.map(item => `
                <div class="history-item" data-timestamp="${item.timestamp}">
                    <div class="history-item-header">
                        <span class="history-item-method ${item.method.toLowerCase()}">${item.method}</span>
                        <div class="history-item-actions">
                            <span class="history-item-time">${formatTime(item.timestamp)}</span>
                            <button class="history-item-delete" title="删除此记录">
                                <span class="button-icon">×</span>
                            </button>
                        </div>
                    </div>
                    <div class="history-item-url">${item.url}</div>
                </div>
            `).join('');

            // 为所有删除按钮添加事件监听
            const deleteButtons = elements.historyList.querySelectorAll('.history-item-delete');
            deleteButtons.forEach(button => {
                button.addEventListener('click', (e) => {
                    e.stopPropagation();
                    const historyItem = (e.target as HTMLElement).closest('.history-item');
                    if (historyItem) {
                        pendingDeleteTimestamp = Number(historyItem.getAttribute('data-timestamp'));
                        if (elements.deleteDialog) {
                            elements.deleteDialog.style.display = 'flex';
                        }
                    }
                });
            });
        } catch (error) {
            console.error('加载历史记录失败:', error);
        }
    }

    /**
     * 添加删除单条历史记录的函数
     */
    function deleteHistoryItem(timestamp: number) {
        try {
            const history = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY) || '[]') as HistoryItem[];
            const itemIndex = history.findIndex(item => item.timestamp === timestamp);
            
            if (itemIndex !== -1) {
                const deletedItem = history[itemIndex];
                const newHistory = history.filter(item => item.timestamp !== timestamp);
                localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify(newHistory));
                
                // 添加到撤销栈
                undoStack.push({
                    type: 'delete',
                    items: [deletedItem]
                });
                
                updateHistoryList();
                updateUndoButton();
            }
        } catch (error) {
            console.error('删除历史记录失败:', error);
        }
    }

    /**
     * 设置历史记录功能
     */
    function setupHistory() {

        // 更新历史记录显示
        updateHistoryList();

        // 显示确认对话框
        elements.clearHistory?.addEventListener('click', () => {
            if (elements.confirmDialog) {
                elements.confirmDialog.style.display = 'flex';
            }
        });

        // 取消清空
        elements.cancelClear?.addEventListener('click', () => {
            if (elements.confirmDialog) {
                elements.confirmDialog.style.display = 'none';
            }
        });

        // 确认清空
        elements.confirmClear?.addEventListener('click', () => {
            try {
                const currentHistory = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY) || '[]') as HistoryItem[];
                if (currentHistory.length > 0) {
                    undoStack.push({
                        type: 'clear',
                        items: currentHistory
                    });
                }
                localStorage.removeItem(STORAGE_KEYS.HISTORY);
                updateHistoryList();
                updateUndoButton();
            } catch (error) {
                console.error('清空历史记录失败:', error);
            }
            if (elements.confirmDialog) {
                elements.confirmDialog.style.display = 'none';
            }
        });

        // 撤销清空
        elements.undoHistory?.addEventListener('click', () => {
            if (undoStack.length === 0) return;

            try {
                const lastAction = undoStack.pop()!;
                const currentHistory = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY) || '[]') as HistoryItem[];
                
                if (lastAction.type === 'clear') {
                    // 恢复清空的所有记录
                    localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify(lastAction.items));
                } else {
                    // 恢复单条删除的记录
                    currentHistory.unshift(...lastAction.items);
                    localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify(currentHistory));
                }
                
                updateHistoryList();
                updateUndoButton();
            } catch (error) {
                console.error('恢复记录失败:', error);
            }
        });

        // 取消删除
        elements.cancelDelete?.addEventListener('click', () => {
            if (elements.deleteDialog) {
                elements.deleteDialog.style.display = 'none';
            }
            pendingDeleteTimestamp = null;
        });

        // 确认删除
        elements.confirmDelete?.addEventListener('click', () => {
            if (pendingDeleteTimestamp !== null) {
                deleteHistoryItem(pendingDeleteTimestamp);
                if (elements.deleteDialog) {
                    elements.deleteDialog.style.display = 'none';
                }
                pendingDeleteTimestamp = null;
            }
        });

        // 点击历史记录项
        elements.historyList?.addEventListener('click', (event) => {
            const historyItem = (event.target as HTMLElement).closest('.history-item');
            if (!historyItem) return;

            const timestamp = Number(historyItem.getAttribute('data-timestamp'));
            const history = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY) || '[]') as HistoryItem[];
            const item = history.find(h => h.timestamp === timestamp);

            if (item) {
                // 更新 URL 选择框
                const matchedApi = API_CONFIG.find(api => api.url === item.url);
                if (matchedApi) {
                    elements.urlSelect.value = item.url;
                } else {
                    elements.urlSelect.value = 'custom';
                }

                // 更新 URL 输入框
                elements.urlInput.value = item.url;

                // 更新请求方法
                elements.methodSelect.value = item.method;

                // 更新参数
                elements.paramsTextarea.value = item.params;

                // 格式化参数
                try {
                    const params = item.params.trim();
                    if (params) {
                        const formatted = JSON.stringify(JSON.parse(params), null, 2);
                        elements.paramsTextarea.value = formatted;
                    }
                } catch (error) {
                    console.error('参数格式化失败:', error);
                }

                // 更新请求方法选项
                updateMethodOptions(item.url);

                // 更新模板选项
                updateTemplateOptions();

                // 恢复响应结果
                if (item.response) {
                    elements.responseOutput.innerHTML = item.response;
                } else {
                    elements.responseOutput.textContent = '';
                }

                // 恢复状态码
                if (elements.statusCode && item.statusCode) {
                    elements.statusCode.textContent = item.statusCode;
                    elements.statusCode.className = `status-code ${item.success ? 'success' : 'error'}`;
                } else if (elements.statusCode) {
                    elements.statusCode.textContent = '';
                    elements.statusCode.className = 'status-code';
                }

                // 高亮选中的历史记录
                const allHistoryItems = elements.historyList?.querySelectorAll('.history-item');
                allHistoryItems?.forEach(item => {
                    item.classList.remove('active');
                });
                historyItem.classList.add('active');

                // 滚动参数框到顶部
                elements.paramsTextarea.scrollTop = 0;
                // 滚动响应框到顶部
                elements.responseOutput.scrollTop = 0;
            }
        });

        // 添加导出功能
        elements.exportHistory?.addEventListener('click', () => {
            try {
                const history = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY) || '[]') as HistoryItem[];
                if (history.length === 0) {
                    alert('没有历史记录可导出');
                    return;
                }

                const content = history.map(item => {
                    // 格式化参数
                    let formattedParams = '';
                    try {
                        formattedParams = JSON.stringify(JSON.parse(item.params), null, 2);
                    } catch {
                        formattedParams = item.params;
                    }

                    // 格式化响应
                    let formattedResponse = '';
                    if (item.response) {
                        try {
                            // 移除HTML标签
                            const tempDiv = document.createElement('div');
                            tempDiv.innerHTML = item.response;
                            const plainText = tempDiv.textContent || tempDiv.innerText;
                            // 尝试格式化JSON
                            formattedResponse = JSON.stringify(JSON.parse(plainText), null, 2);
                        } catch {
                            formattedResponse = item.response.replace(/<[^>]*>/g, '');
                        }
                    }

                    return `==================== 请求记录 ====================
时间: ${formatTime(item.timestamp)}
请求方法: ${item.method}
请求地址: ${item.url}
状态: ${item.success ? '成功' : '失败'}${item.statusCode ? ' (' + item.statusCode + ')' : ''}

请求参数:
${formattedParams}

响应结果:
${formattedResponse || '无响应数据'}

================================================

`;
                }).join('\n');

                const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
                const url = URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;
                link.download = `ollama_api_history_${formatFileName(Date.now())}.txt`;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                URL.revokeObjectURL(url);
            } catch (error) {
                console.error('导出历史记录失败:', error);
                alert('导出失败');
            }
        });
    }

    /**
     * 保存请求历史
     */
    function saveToHistory(url: string, method: string, params: string, success: boolean, response?: string, statusCode?: string) {
        try {
            const history = JSON.parse(localStorage.getItem(STORAGE_KEYS.HISTORY) || '[]') as HistoryItem[];
            history.unshift({
                timestamp: Date.now(),
                url,
                method,
                params,
                success,
                response,
                statusCode
            });
            localStorage.setItem(STORAGE_KEYS.HISTORY, JSON.stringify(history.slice(0, 50)));
            updateHistoryList();
        } catch (error) {
            console.error('保存历史记录失败:', error);
        }
    }

    /**
     * 保存最后使用的 API 设置
     */
    function saveLastApiSettings() {
        try {
            localStorage.setItem(STORAGE_KEYS.LAST_API, JSON.stringify({
                url: elements.urlInput.value,
                method: elements.methodSelect.value,
                params: elements.paramsTextarea.value
            }));
        } catch (error) {
            console.error('保存设置失败:', error);
        }
    }

    /**
     * 加载最后使用的 API 设置
     */
    function loadLastApiSettings() {
        try {
            const lastApi = localStorage.getItem(STORAGE_KEYS.LAST_API);
            if (lastApi) {
                const { url, method, params } = JSON.parse(lastApi);
                elements.urlInput.value = url;
                elements.methodSelect.value = method;
                elements.paramsTextarea.value = params;
            }
        } catch (error) {
            console.error('加载设置失败:', error);
        }
    }

    /**
     * 参数模板配置
     */
    interface ParamTemplate {
        name: string;
        params: any;
        apiType: string; // 对应的 API 类型
    }

    const PARAM_TEMPLATES: Record<string, ParamTemplate> = {
        'chat-simple': {
            name: '简单对话',
            apiType: '/api/chat',
            params: {
                model: "qwen2.5:0.5b",
                messages: [
                    { role: "user", content: "你好" }
                ],
                stream: false
            }
        },
        'chat-system': {
            name: '带系统提示的对话',
            apiType: '/api/chat',
            params: {
                model: "qwen2.5:0.5b",
                messages: [
                    { role: "system", content: "你是一个有帮助的AI助手" },
                    { role: "user", content: "你好" }
                ],
                stream: false
            }
        },
        'generate-simple': {
            name: '简单生成',
            apiType: '/api/generate',
            params: {
                model: "qwen2.5:0.5b",
                prompt: "写一首诗",
                stream: false
            }
        },
        'generate-options': {
            name: '带选项的生成',
            apiType: '/api/generate',
            params: {
                model: "qwen2.5:0.5b",
                prompt: "写一首诗",
                stream: false,
                options: {
                    temperature: 0.7,
                    top_p: 0.9,
                    top_k: 40,
                    seed: 42
                }
            }
        },
        'embeddings': {
            name: '文本向量化',
            apiType: '/api/embeddings',
            params: {
                model: "qwen2.5:0.5b",
                prompt: "Hello world"
            }
        },
        'pull-model': {
            name: '拉取模型',
            apiType: '/api/pull',
            params: {
                name: "qwen2.5:0.5b",
                stream: false
            }
        },
        'show-model': {
            name: '查看模型信息',
            apiType: '/api/show',
            params: {
                name: "qwen2.5:0.5b"
            }
        },
        'copy-model': {
            name: '复制模型',
            apiType: '/api/copy',
            params: {
                source: "qwen2.5:0.5b",
                destination: "qwen2.5:0.5b-copy"
            }
        }
    };

    /**
     * 格式化 JSON 参数
     */
    function formatJsonParams() {
        try {
            const params = elements.paramsTextarea.value.trim();
            if (!params) return;
            
            const formatted = JSON.stringify(JSON.parse(params), null, 2);
            elements.paramsTextarea.value = formatted;
        } catch (error) {
            showError('JSON 格式化失败，请检查参数格式');
        }
    }

    /**
     * 更新请求方法选项
     */
    function updateMethodOptions(apiUrl: string) {
        const api = API_CONFIG.find(api => api.url === apiUrl);
        if (!api) return;

        elements.methodSelect.innerHTML = '';
        
        api.methods.forEach(method => {
            const option = document.createElement('option');
            option.value = method;
            option.textContent = method;
            option.selected = method === api.defaultMethod;
            elements.methodSelect.appendChild(option);
        });
    }

    /**
     * 处理 API 选择变化
     */
    function handleApiSelection() {
        const selectedUrl = elements.urlSelect.value;
        const selectedApi = selectedUrl === 'custom' 
            ? null 
            : API_CONFIG.find(api => api.url === selectedUrl);

        if (selectedApi) {
            // 如果选择的是预定义 API
            elements.urlInput.value = selectedApi.url;
            elements.paramsTextarea.value = JSON.stringify(selectedApi.example, null, 2);
            updateMethodOptions(selectedApi.url);
        } else {
            // 如果选择的是自定义
            elements.urlInput.value = '';
            elements.urlInput.placeholder = '输入自定义 API 地址';
            elements.paramsTextarea.value = '';
            // 重置为默认请求方法选项
            elements.methodSelect.innerHTML = `
                <option value="GET">GET</option>
                <option value="POST" selected>POST</option>
                <option value="DELETE">DELETE</option>
            `;
        }

        // 重置模板选择
        if (elements.templateSelect) {
            elements.templateSelect.value = '';
        }
    }

    /**
     * 处理 URL 输入变化
     */
    function handleUrlInput() {
        const currentUrl = elements.urlInput.value.trim();
        const matchedApi = API_CONFIG.find(api => api.url === currentUrl);
        
        // 更新 URL 选择框
        if (matchedApi) {
            elements.urlSelect.value = currentUrl;
        } else {
            elements.urlSelect.value = 'custom';
        }

        // 更新请求方法选项
        if (matchedApi) {
            updateMethodOptions(currentUrl);
        } else {
            elements.methodSelect.innerHTML = `
                <option value="GET">GET</option>
                <option value="POST" selected>POST</option>
                <option value="DELETE">DELETE</option>
            `;
        }

        // 更新模板选项
        updateTemplateOptions();
    }

    /**
     * 验证请求方法
     */
    function validateMethod(url: string, method: string): boolean {
        const api = API_CONFIG.find(api => api.url === url);
        if (!api) return true; // 自定义 URL 允许任何方法
        return api.methods.includes(method as HttpMethod);
    }

    /**
     * JSON 语法高亮
     */
    function highlightJson(json: string): string {
        // 处理数组格式化
        const formatArray = (arr: any[]): string => {
            if (arr.length > 10 && arr.every(item => typeof item === 'number')) {
                // 如果是长数字数组，只显示前5个和后5个
                const firstFive = arr.slice(0, 5);
                const lastFive = arr.slice(-5);
                return `[${firstFive.join(', ')}, ... ${arr.length - 10} more items ..., ${lastFive.join(', ')}]`;
            }
            return JSON.stringify(arr);
        };

        // 预处理 JSON 字符串
        const processJson = (obj: any): any => {
            if (Array.isArray(obj)) {
                return formatArray(obj);
            }
            if (typeof obj === 'object' && obj !== null) {
                const newObj: any = {};
                for (const key in obj) {
                    newObj[key] = processJson(obj[key]);
                }
                return newObj;
            }
            return obj;
        };

        try {
            const parsed = JSON.parse(json);
            const processed = processJson(parsed);
            const formatted = JSON.stringify(processed, null, 2);

            return formatted.replace(
                /("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?|\[\s*\d+(?:\s*,\s*\d+)*\s*\])/g,
                (match) => {
                    let cls = 'json-number';
                    if (/^"/.test(match)) {
                        if (/:$/.test(match)) {
                            cls = 'json-key';
                        } else {
                            cls = 'json-string';
                        }
                    } else if (/true|false/.test(match)) {
                        cls = 'json-boolean';
                    } else if (/null/.test(match)) {
                        cls = 'json-null';
                    } else if (/\[.*\]/.test(match)) {
                        cls = 'json-array';
                    }
                    return `<span class="${cls}">${match}</span>`;
                }
            );
        } catch (e) {
            return json;
        }
    }

    /**
     * 格式化响应数据并添加行号
     */
    function formatResponse(data: string): string {
        try {
            const parsed = JSON.parse(data);
            const formatted = JSON.stringify(parsed, null, 2);
            const highlighted = highlightJson(formatted);
            return highlighted.split('\n').map(line => 
                `<span class="line">${line}</span>`
            ).join('\n');
        } catch {
            return data.split('\n').map(line => 
                `<span class="line">${line}</span>`
            ).join('\n');
        }
    }

    /**
     * 显示错误信息
     */
    function showError(message: string) {
        elements.responseOutput.textContent = `错误: ${message}`;
        if (elements.statusCode) {
            elements.statusCode.textContent = '错误';
            elements.statusCode.className = 'status-code error';
        }
    }

    /**
     * 设置主题切换功能
     */
    function setupThemeToggle() {
        elements.themeToggle?.addEventListener('click', () => {
            const isDark = document.body.getAttribute('data-theme') === 'dark';
            document.body.setAttribute('data-theme', isDark ? 'light' : 'dark');
            (elements.themeToggle?.querySelector('.theme-icon') as HTMLElement).textContent = isDark ? '🌙' : '☀️';
        });
    }

    /**
     * 设置复制按钮功能
     */
    function setupCopyButton() {
        if (!elements.copyButton) return;

        elements.copyButton.addEventListener('click', async (e) => {
            // 阻止事件冒泡，防止触发响应区域的收起
            e.stopPropagation();

            if (!elements.responseOutput?.textContent) return;

            const originalHTML = elements.copyButton!.innerHTML;
            try {
                await navigator.clipboard.writeText(elements.responseOutput.textContent);
                elements.copyButton!.innerHTML = '<span class="button-icon">✅</span>已复制';
                elements.copyButton!.style.borderColor = 'var(--success-color)';
                elements.copyButton!.style.color = 'var(--success-color)';
                
                setTimeout(() => {
                    if (!elements.copyButton) return;
                    elements.copyButton.innerHTML = originalHTML;
                    elements.copyButton.style.borderColor = '';
                    elements.copyButton.style.color = '';
                }, 2000);
            } catch (err) {
                console.error('复制失败:', err);
                if (!elements.copyButton) return;
                elements.copyButton.innerHTML = '<span class="button-icon">❌</span>复制失败';
                elements.copyButton.style.borderColor = 'var(--error-color)';
                elements.copyButton.style.color = 'var(--error-color)';
                
                setTimeout(() => {
                    if (!elements.copyButton) return;
                    elements.copyButton.innerHTML = originalHTML;
                    elements.copyButton.style.borderColor = '';
                    elements.copyButton.style.color = '';
                }, 2000);
            }
        });
    }

    /**
     * 处理 API 请求
     */
    async function handleRequest() {
        elements.responseOutput.textContent = '';
        let requestSuccess = false;

        // 验证 URL
        if (!elements.urlInput.value.trim()) {
            showError('请输入有效的 API 地址');
            return;
        }

        // 验证请求方法
        if (!validateMethod(elements.urlInput.value, elements.methodSelect.value)) {
            showError('当前 API 不支持该请求方法');
            return;
        }

        const requestOptions: RequestInit = {
            method: elements.methodSelect.value,
            headers: {
                'Content-Type': 'application/json'
            }
        };

        // 设置超时
        const timeout = Number(elements.timeoutInput.value) || 30;
        const controller = new AbortController();
        const timeoutId = setTimeout(() => controller.abort(), timeout * 1000);
        requestOptions.signal = controller.signal;

        // 处理请求参数
        if (elements.methodSelect.value !== 'GET') {
            try {
                const params = elements.paramsTextarea.value.trim();
                if (!params) {
                    showError('请求参数不能为空');
                    return;
                }
                const parsedParams = JSON.parse(params);
                requestOptions.body = JSON.stringify(parsedParams);
            } catch (error) {
                showError('请求参数格式不正确，请确保是有效的 JSON 格式');
                return;
            }
        }

        if (elements.loading) {
            elements.loading.style.display = 'flex';
        }

        try {
            const response = await fetch(elements.urlInput.value, requestOptions);
            requestSuccess = response.ok;
            
            if (elements.statusCode) {
                elements.statusCode.textContent = `${response.status} ${response.statusText}`;
                elements.statusCode.className = `status-code ${response.ok ? 'success' : 'error'}`;
            }

            const contentType = response.headers.get("content-type");
            let responseText = '';

            if (contentType?.includes("text/event-stream") || contentType?.includes("application/x-ndjson")) {
                await handleStreamResponse(response);
                responseText = elements.responseOutput.innerHTML;
            } else {
                await handleNormalResponse(response, contentType);
                responseText = elements.responseOutput.innerHTML;
            }

            if (requestSuccess) {
                saveToHistory(
                    elements.urlInput.value,
                    elements.methodSelect.value,
                    elements.paramsTextarea.value,
                    true,
                    responseText,
                    elements.statusCode?.textContent ?? undefined
                );
                saveLastApiSettings();
            }
        } catch (error) {
            if (error instanceof Error) {
                if (error.name === 'AbortError') {
                    showError(`请求超时 (${timeout}秒)`);
                } else {
                    showError(error.message);
                }
            } else {
                showError('未知错误');
            }
            saveToHistory(
                elements.urlInput.value,
                elements.methodSelect.value,
                elements.paramsTextarea.value,
                false,
                error instanceof Error ? error.message : '未知错误',
                '错误'
            );
        } finally {
            clearTimeout(timeoutId);
            if (elements.loading) {
                elements.loading.style.display = 'none';
            }
        }
    }

    /**
     * 处理流式响应
     */
    async function handleStreamResponse(response: Response) {
        const reader = response.body?.getReader();
        const decoder = new TextDecoder();
        let buffer = '';

        if (reader) {
            try {
                while (true) {
                    const { done, value } = await reader.read();
                    if (done) break;
                    
                    buffer += decoder.decode(value, { stream: true });
                    const lines = buffer.split('\n');
                    buffer = lines.pop() || '';

                    for (const line of lines) {
                        if (line.trim()) {
                            const formattedLine = formatResponse(line);
                            elements.responseOutput.innerHTML += formattedLine + '\n';
                            elements.responseOutput.scrollTop = elements.responseOutput.scrollHeight;
                        }
                    }
                }
                
                if (buffer.trim()) {
                    elements.responseOutput.innerHTML += formatResponse(buffer) + '\n';
                }
            } catch (error) {
                showError('读取流式响应时发生错误');
            }
        }
    }

    /**
     * 处理普通响应
     */
    async function handleNormalResponse(response: Response, contentType: string | null) {
        try {
            if (contentType?.includes("application/json")) {
                const data = await response.json();
                elements.responseOutput.innerHTML = highlightJson(JSON.stringify(data, null, 2));
            } else {
                const text = await response.text();
                elements.responseOutput.innerHTML = formatResponse(text);
            }
        } catch (error) {
            showError('解析响应数据时发生错误');
        }
    }

    /**
     * 设置请求按钮功能
     */
    function setupRequestButton() {
        document.getElementById('sendRequest')?.addEventListener('click', handleRequest);
    }

    /**
     * 更新模板选项
     */
    function updateTemplateOptions() {
        const currentUrl = elements.urlInput.value.trim();
        const apiType = currentUrl.split('/api/')[1]?.split('?')[0];
        
        elements.templateSelect.innerHTML = '<option value="">选择模板</option>';
        
        if (apiType && validateMethod(currentUrl, elements.methodSelect.value)) {
            Object.entries(PARAM_TEMPLATES).forEach(([key, template]) => {
                if (template.apiType === `/api/${apiType}`) {
                    const option = document.createElement('option');
                    option.value = key;
                    option.textContent = template.name;
                    elements.templateSelect.appendChild(option);
                }
            });
        }
    }

    /**
     * 设置参数模板功能
     */
    function setupTemplates() {
        // 监听 URL 变化
        elements.urlSelect.addEventListener('change', () => {
            handleApiSelection();
            updateTemplateOptions();
        });

        // 用防抖处理输入事件
        let inputTimeout: number;
        elements.urlInput.addEventListener('input', () => {
            clearTimeout(inputTimeout);
            inputTimeout = setTimeout(() => {
                handleUrlInput();
            }, 300) as unknown as number;
        });

        // 监听模板选择
        elements.templateSelect.addEventListener('change', () => {
            const selected = elements.templateSelect.value;
            if (selected && PARAM_TEMPLATES[selected]) {
                elements.paramsTextarea.value = JSON.stringify(PARAM_TEMPLATES[selected].params, null, 2);
            }
        });

        // 初始化模板选项
        updateTemplateOptions();
    }

    /**
     * 设置快捷键
     */
    function setupShortcuts() {
        document.addEventListener('keydown', (event) => {
            // Ctrl/Cmd + Enter 发送请求
            if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
                event.preventDefault();
                handleRequest();
            }
            // Ctrl/Cmd + L 清空响应
            if ((event.ctrlKey || event.metaKey) && event.key === 'l') {
                event.preventDefault();
                elements.responseOutput.textContent = '';
            }
            // Ctrl/Cmd + Shift + F 格式化参数
            if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'F') {
                event.preventDefault();
                formatJsonParams();
            }
            // Esc 取消加载
            if (event.key === 'Escape' && elements.loading?.style.display === 'flex') {
                event.preventDefault();
                if (elements.loading) {
                    elements.loading.style.display = 'none';
                }
            }
        });
    }

    // 初始化界面
    function initialize() {
        // 加载主题设置
        const savedTheme = localStorage.getItem(STORAGE_KEYS.THEME);
        if (savedTheme) {
            document.body.setAttribute('data-theme', savedTheme);
            if (elements.themeToggle?.querySelector('.theme-icon')) {
                (elements.themeToggle.querySelector('.theme-icon') as HTMLElement).textContent = 
                    savedTheme === 'dark' ? '☀️' : '🌙';
            }
        }

        // 加载最后使用的 API 设置
        loadLastApiSettings();

        // 设置事件监听器
        handleApiSelection();
        setupThemeToggle();
        setupCopyButton();
        setupRequestButton();
        setupShortcuts();
        setupHistory();
        setupTemplates();
        elements.formatButton?.addEventListener('click', formatJsonParams);

        // 设置初始 URL 和参数
        handleApiSelection();
        handleUrlInput();

        // 设置响应区域的收起/展开功能
        elements.responseHeader?.addEventListener('click', () => {
            elements.responseContainer?.classList.toggle('collapsed');
        });

        // 设置参数区域的收起/展开功能
        elements.paramsHeader?.addEventListener('click', (e) => {
            // 如果点击的是工具栏区域，不触发收起/展开
            if ((e.target as HTMLElement).closest('.params-tools')) return;
            elements.paramsContainer?.classList.toggle('collapsed');
        });

        // 设置历史面板的收起/展开功能
        elements.historyHeader?.addEventListener('click', (e) => {
            // 如果点击的是操作按钮区域，不触发收起/展开
            if ((e.target as HTMLElement).closest('.history-actions')) return;
            elements.historyPanel?.classList.toggle('collapsed');
        });
    }

    // 初始化应用
    initialize();

    // 在点击历史记录外的区域时关闭对话框
    document.addEventListener('click', (event) => {
        if (
            (elements.confirmDialog && event.target === elements.confirmDialog) ||
            (elements.deleteDialog && event.target === elements.deleteDialog)
        ) {
            elements.confirmDialog!.style.display = 'none';
            elements.deleteDialog!.style.display = 'none';
            undoStack = [];  // 清空撤销栈
            updateUndoButton();
        }
    });

    // 添加更新撤销按钮的函数
    function updateUndoButton() {
        if (!elements.undoHistory) return;

        if (undoStack.length > 0) {
            const lastAction = undoStack[undoStack.length - 1];
            elements.undoHistory.style.display = 'flex';
            elements.undoHistory.innerHTML = `<span class="button-icon">↩️</span>撤销${lastAction.type === 'clear' ? '清空' : '删除'} (${undoStack.length})`;
        } else {
            elements.undoHistory.style.display = 'none';
        }
    }

    // 添加格式化文件名的函数
    function formatFileName(timestamp: number): string {
        const date = new Date(timestamp);
        return date.toLocaleString('zh-CN', {
            year: 'numeric',
            month: '2-digit',
            day: '2-digit',
            hour: '2-digit',
            minute: '2-digit',
            second: '2-digit'
        }).replace(/[\/\s:]/g, '');  // 移除斜杠、空格和冒号
    }
});